﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(AutoCreateTunnel), true)]
public class AutoCreateTunnelEditor : Editor
{

    private AutoCreateTunnel m_Script;

    private GUIStyle m_HandleLable= new GUIStyle();

    public enum EnumType
    {
        点序,
        顶点位置,
        UV,
        法线
    }

    public enum DebugData
    {
        斜率值,
        斜率差
    }

    //public enum CaculateType { 
    //    普通模式,
    //    高性能模式
    //}


    private void Awake()
    {
        m_Script = target as AutoCreateTunnel;
        m_HandleLable.normal.textColor = Color.red;
        m_HandleLable.fontSize = 25;
    }

    private EnumType m_TempletType = EnumType.UV;

    private DebugData m_LineDebugData = DebugData.斜率值;

    //private CaculateType m_CaculateType = CaculateType.普通模式;

    private bool IsShowMeshInfo = false;

    public override void OnInspectorGUI()
    {
        GUILayout.BeginHorizontal();
        if (GUILayout.Button("加载数据"))
        {
            Debug.LogError("加载保存数据");
        }
        if (GUILayout.Button("初始化数据"))
        {
            m_Script.InitData();
        }
        GUILayout.EndHorizontal();
        if (GUILayout.Button("新增节点")) {
            AddNewSingleNode();
        }
        if (GUILayout.Button("自动计算贝塞尔曲线")) {
            //TODO 自动计算贝塞尔曲线
            Debug.LogError("自动计算贝塞尔曲线");
            m_Script.InitData();
            m_Script.AutoCaculateBezierCure();
        }
        GUILayout.BeginHorizontal();
        if (GUILayout.Button("重置数据")) {
            Debug.LogError("重置数据");
            ResetBezierList();
        }
        if (GUILayout.Button("清除所有数据"))
        {
            Debug.LogError("清除所有数据");
            CleanAllData();
        }
        GUILayout.EndHorizontal();
        GUILayout.BeginHorizontal();
        if (GUILayout.Button("重置当前的贝塞尔点"))
        {
            ResetSingleBezierPoint();
        }
        if (GUILayout.Button("重置当前节点")) {
            RestSingleNode();
        }
        GUILayout.EndHorizontal();
        if (GUILayout.Button("保存数据"))
        {
            Debug.LogError("保存数据");
        }
        GUILayout.BeginHorizontal();
        m_TempletType = (EnumType)EditorGUILayout.EnumPopup("检视类型：", m_TempletType);
        GUILayout.EndHorizontal();
        GUILayout.BeginHorizontal();
        m_LineDebugData = (DebugData)EditorGUILayout.EnumPopup("曲线调试：", m_LineDebugData);
        GUILayout.EndHorizontal();
        //GUILayout.BeginHorizontal();
        //m_CaculateType = (CaculateType)EditorGUILayout.EnumPopup("计算模式：", m_CaculateType);
        //GUILayout.EndHorizontal();

        if (GUILayout.Button("生成模型信息")) {
            IsShowMeshInfo = true;
        }

        if (GUILayout.Button("开始自动化构件"))
        {
            Debug.LogError("开始自动化构件");
            m_Script.CreateAutoTunnel();
        }
        if (GUILayout.Button("导出Object格式模型")) {
            Debug.Log("<color>开始导出Obj模型</color>");
            string path = @"Assets/Export/Model/"+ m_Script.TemplteMesh.ModelName+"/";
            if (m_Script.TemplteMesh.ModelName == null) {
                Debug.LogError("模板名称为空:");
                return;
            }
            ObjExporter.MeshToFile(m_Script.SpwanTunnelMesh.MeshData, null, m_Script.TemplteMesh.ModelName, path, m_Script.TemplteMesh.ModelName+".obj");
            AssetDatabase.Refresh(); //刷新
            Debug.Log("<color>导出Obj模型结束</color>");
        }
        base.OnInspectorGUI();
    }

    public void DrawCaculateBeizerGradientByTwoLine() {

        for (int i = 0; i < m_Script.m_PathList.Count - 2;i++) {
            Vector3 preStartNode = m_Script.m_PathList[i].position;
            Vector3 preEndNode = m_Script.m_PathList[i+1].position;
            Vector3 preBeizerNode = m_Script.m_BezierList[i].position;

            Vector3 nextStartNode = m_Script.m_PathList[i+1].position;
            Vector3 nextEndNode = m_Script.m_PathList[i+2].position;
            Vector3 nextBeizerNode = m_Script.m_BezierList[i+1].position;

            Vector3 preGradient = m_Script.BezierCurveGradient(preStartNode, preEndNode, preBeizerNode,1);
            Vector3 nextGradient = m_Script.BezierCurveGradient(nextStartNode, nextEndNode, nextBeizerNode, 0);

            float angle = Vector3.Angle(preGradient, nextGradient);
            Handles.Label(preEndNode, angle.ToString(), m_HandleLable);
        }
        
    }





    private void AddNewSingleNode()
    {
        UnityEngine.Object[] selects = Selection.objects;
        if (selects.Length > 0)
        {
            GameObject tagert = selects[0] as GameObject;
            string name = tagert.name;
            int index = -1;
            for (int i = 0; i < m_Script.m_PathList.Count; i++)
            {
                Transform tempNode = m_Script.m_PathList[i];
                if (tempNode.name == name)
                {
                    index = i;
                }
                if (index == -1)
                    continue;
                if (i >= index) {
                    tempNode.name = (i+1)+"";
                }
            }
            GameObject node = new GameObject(index + "");
            node.transform.parent = m_Script.m_PathList[index].transform.parent;
            node.transform.position = m_Script.m_PathList[index].transform.position;
            GameObject bezierPoint = new GameObject("Bezier_" + index);
            bezierPoint.transform.parent = node.transform;
            bezierPoint.transform.localPosition = Vector3.zero;
            m_Script.m_BezierList.Insert(index, bezierPoint.transform);
            m_Script.m_PathList.Insert(index, node.transform);
            node.transform.SetSiblingIndex(index);
        }
    }

    private void RestSingleNode()
    {
        UnityEngine.Object[] selects = Selection.objects;
        if (selects.Length > 0)
        {
            GameObject tagert = selects[0] as GameObject;
            for (int i = 0; i < m_Script.m_PathList.Count; i++)
            {
                Transform node = m_Script.m_PathList[i];
                if (node.name == tagert.name)
                {
                    node.position = m_Script.m_CopyPosList[i];
                    break;
                }
            }
        }
    }

    private void ResetSingleBezierPoint()
    {
        UnityEngine.Object[] selects = Selection.objects;
        if (selects.Length > 0) {
            GameObject tagert = selects[0] as GameObject;
            int index = 0;
            for (int i = 0; i < m_Script.m_PathList.Count; i++) {
                Transform node  = m_Script.m_PathList[i];
                if (node.name == tagert.name) {
                    index = i;
                    break;
                }
            }
            if (index < m_Script.m_PathList.Count) {
                m_Script.m_BezierList[index].localPosition = Vector3.zero;
            }
        }
    }

    private void CleanAllData()
    {
        m_Script.ClearAllData();
    }

    private void ResetBezierList() {
        for (int i = 0; i < m_Script.m_BezierList.Count;i++) {
            m_Script.m_BezierList[i].localPosition = Vector3.zero;
        }
    }

    Vector3 m_startPoint = Vector3.zero;
    Vector3 m_endPoint = Vector3.zero;
    Vector3 m_startTangent = Vector3.zero;
    Vector3 m_endTangent = Vector3.zero;
    protected virtual void OnSceneGUI()
    {
        DrawBezierCure();
        DrawUVPoint();
        if (m_LineDebugData == DebugData.斜率值)
        {
            DrawBezierGradient();
        }
        else {
            DrawCaculateBeizerGradientByTwoLine();
        }
        //DrawHandleLabel();
    }

    private void DrawBezierGradient()
    {
        for (int i = 0; i < m_Script.m_PathList.Count - 1; i++)
        {
            Vector3 curStartNode = m_Script.m_PathList[i].position;
            Vector3 curEndNode = m_Script.m_PathList[i + 1].position;
            Vector3 curBeizerNode = m_Script.m_BezierList[i].position;
            if (i == 0) {
                Vector3 gradient = m_Script.BezierCurveGradient(curStartNode, curEndNode, curBeizerNode, 0);
                Handles.Label(curStartNode, "("+ gradient.normalized.x+ ","+ gradient.normalized.y + ","+ gradient.normalized.z + ")", m_HandleLable);
            }
            Vector3 curGradient = m_Script.BezierCurveGradient(curStartNode, curEndNode, curBeizerNode, 1);
            Handles.Label(curEndNode, "(" + curGradient.normalized.x + "," + curGradient.normalized.y + "," + curGradient.normalized.z + ")", m_HandleLable);
        }
    }

    private void DrawUVPoint()
    {
        if (!IsShowMeshInfo) return;
        for (int i = 0; i < m_Script.SpwanTunnelMesh.Vertices.Length; i++)
        {
            if (i == 103 || i == 102) continue;
            Vector3 localPos = m_Script.SpwanTunnelMesh.Vertices[i];
            switch (m_TempletType)
            {
                case EnumType.点序:
                    Handles.Label(m_Script.SpwanTunnelGB.transform.TransformPoint(localPos), i + "", m_HandleLable);
                    break;
                case EnumType.顶点位置:
                    Handles.Label(m_Script.SpwanTunnelGB.transform.TransformPoint(localPos), localPos.ToString(), m_HandleLable);
                    break;
                case EnumType.UV:
                    Vector2 uv = m_Script.SpwanTunnelMesh.UV[i];
                    Handles.Label(m_Script.SpwanTunnelGB.transform.TransformPoint(localPos), "("+ uv.x+ ","+ uv.y+ ")", m_HandleLable);
                    break;
                case EnumType.法线:
                    Vector2 normal = m_Script.SpwanTunnelMesh.Normals[i];
                    Handles.Label(m_Script.SpwanTunnelGB.transform.TransformPoint(localPos), normal.ToString(), m_HandleLable);
                    break;
            }
        }
    }

    private void DrawHandleLabel()
    {
        if (m_Script.DebugVerticeList.Count > 0) {
            for (int i = 0; i < m_Script.DebugVerticeList.Count; i++)
            {
                Handles.color = Color.red;
                Handles.Label(m_Script.DebugVerticeList[i].Position, m_Script.DebugVerticeList[i].Index + "", m_HandleLable);
            }
        }

    }

    private void DrawBezierCure()
    {
        if (m_Script == null)
            return;
        if (m_Script.m_PathList == null)
            return;
        if (m_Script.m_BezierList == null)
            return;
        if (m_Script.m_PathList.Count <= 0)
            return;
        if (m_Script.m_BezierList.Count <= 0)
            return;
        for (int i = 0; i < m_Script.m_PathList.Count-1; i++) {
            Vector3 point = m_Script.m_PathList[i].position;
            Vector3 nextPoint = m_Script.m_PathList[i+1].position;
            Vector3 bezierPoint = m_Script.m_BezierList[i].position;
            int count = m_Script.Segment * 10;
            for (int j = 0; j < count; j++) {
                Vector3 curSegment  = m_Script.BezierCurve(point, nextPoint, bezierPoint,j * 1.0f/ count);
                Vector3 LastSegment = m_Script.BezierCurve(point, nextPoint, bezierPoint, (j+1) * 1.0f / count);
                Handles.color = Color.green;
                Handles.DrawLine(curSegment, LastSegment);
            }
            Handles.color = Color.red;
            Handles.DrawSphere(i, point,Quaternion.identity, m_Script.SphereSize);
            Handles.DrawSphere(i+1, nextPoint, Quaternion.identity, m_Script.SphereSize);
            Vector3 offset = Handles.PositionHandle(bezierPoint, Quaternion.identity);
            m_Script.m_BezierList[i].position = offset;
        }
    }

    /// <summary>
    /// 二次贝塞尔
    /// </summary>
    public Vector3 Bezier_2(Vector3 p0, Vector3 p1, Vector3 p2, float t)
    {
        return (1 - t) * ((1 - t) * p0 + t * p1) + t * ((1 - t) * p1 + t * p2);
    }

}
